package top.xia17.plugins.fast.common.utils;

import cn.hutool.core.util.StrUtil;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.validation.ValidatorAdapter;
import org.springframework.validation.*;
import top.xia17.plugins.fast.common.exceptions.VerifyException;
import top.xia17.plugins.fast.common.spring.SpringContextHolder;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 验证util
 * @author xia17
 * @date 2020/8/4 16:05
 */
@Slf4j
public class VerifyUtil {


    /**
     * 生成BindingResult
     * @param obj /
     * @return /
     */
    public static BindingResult validated(Object obj){
        Validator validator = ValidatorAdapter.get(SpringContextHolder.getApplicationContext(), null);
        BindException exception = new BindException(obj, "参数异常");
        ValidationUtils.invokeValidator(validator,obj,exception);
        return exception;
    }

    /**
     * 验证参数
     * @param obj /
     * @param message /
     */
    public static void valid(Object obj,String message){
        valid(validated(obj),message);
    }

    /**
     * 验证参数
     * @param obj /
     */
    public static void valid(Object obj){
        valid(obj,"");
    }

    /**
     * 验证参数
     * @param bindingResult /
     * @param message /
     */
    public static void valid(@NotNull BindingResult bindingResult, @NotNull String message){
        if (bindingResult.hasErrors()){
            String msg = bindingResult.getFieldErrors().stream()
                    .map(FieldError::getDefaultMessage)
                    .collect(Collectors.joining(","));
            log.error("请求参数异常,{}",msg);
            throw new VerifyException(message +  ',' + msg);
        }
    }




    /**
     * double 小数位数不能大于2
     * @return 大于2 false
     */
    public static boolean twoDecimalPlaces(double d){
        String s = "" + d ;
        int i = s.indexOf(".");
        if (i == -1){
            return false;
        }
        return s.length() - i - 1 > 2 ;
    }

    /**
     * 值一定为NULL
     * @param d /
     * @param msg /
     */
    public static void isNull(Object d , String msg){
        if (d != null){
            sendError(msg);
        }
    }

    /**
     * 值不为NUll
     * @param d /
     * @param msg /
     */
    public static void notNull(Object d , String msg){
        if (d == null){
            sendError(msg);
        }
    }

    /**
     * 值不为empty
     * @param s /
     * @param msg /
     */
    public static void notEmpty(String s , String msg){
        if (StrUtil.isEmpty(s)){
            sendError(msg);
        }
    }

    /**
     * 值为 empty
     * @param s /
     * @param msg /
     */
    public static void isEmpty(String s,String msg){
        if (StrUtil.isNotEmpty(s)){
            sendError(msg);
        }
    }

    /**
     * 值不为blank
     * @param s /
     * @param msg /
     */
    public static void notBlank(String s , String msg){
        if (StrUtil.isBlank(s)){
            sendError(msg);
        }
    }

    /**
     * 值为blank
     * @param s /
     * @param msg /
     */
    public static void isBlank(String s , String msg){
        if (StrUtil.isNotBlank(s)){
            sendError(msg);
        }
    }

    /**
     * 日期 var1 大于 val2
     * @param var1 /
     * @param var2 /
     * @param msg /
     */
    public static void dateGt(LocalDate var1 , LocalDate var2 , String msg){
        if (var1.isEqual(var2)){
            sendError(msg);
        }
        if (var1.isBefore(var2)){
            sendError(msg);
        }
    }

    /**
     * 日期 var1 大于等于 val2
     * @param var1 /
     * @param var2 /
     * @param msg /
     */
    public static void dateGtAndEquals(LocalDate var1 , LocalDate var2 , String msg){
        if (var1.isBefore(var2)){
            sendError(msg);
        }
    }

    /**
     * 日期 var1 小于 val2
     * @param var1 /
     * @param var2 /
     * @param msg /
     */
    public static void dateLt(LocalDate var1 , LocalDate var2 , String msg){
        if (var1.isEqual(var2)){
            sendError(msg);
        }
        if (var1.isAfter(var2)){
            sendError(msg);
        }
    }

    /**
     * 日期 var1 小于等于 val2
     * @param var1 /
     * @param var2 /
     * @param msg /
     */
    public static void dateLtAndEquals(LocalDate var1 , LocalDate var2 , String msg){
        if (var1.isAfter(var2)){
            sendError(msg);
        }
    }

    /**
     * 日期 val1 等于时间 val2
     * @param var1 /
     * @param var2 /
     * @param msg /
     */
    public static void dateEquals(LocalDate var1 , LocalDate var2 , String msg){
        if (!var1.isEqual(var2)){
            sendError(msg);
        }
    }

    /**
     * 日期 val1 不等于时间 val2
     * @param var1 /
     * @param var2 /
     * @param msg /
     */
    public static void dateNotEquals(LocalDate var1 , LocalDate var2 , String msg){
        if (var1.isEqual(var2)){
            sendError(msg);
        }
    }

    /**
     * 时间 var1 大于 val2
     * @param var1 /
     * @param var2 /
     * @param msg /
     */
    public static void timeGt(LocalDateTime var1 , LocalDateTime var2 , String msg){
        if (var1.isEqual(var2)){
            sendError(msg);
        }
        if (var1.isBefore(var2)){
            sendError(msg);
        }
    }

    /**
     * 时间 var1 大于等于 val2
     * @param var1 /
     * @param var2 /
     * @param msg /
     */
    public static void timeGtAndEquals(LocalDateTime var1 , LocalDateTime var2 , String msg){
        if (var1.isBefore(var2)){
            sendError(msg);
        }
    }

    /**
     * 时间 var1 小于 val2
     * @param var1 /
     * @param var2 /
     * @param msg /
     */
    public static void timeLt(LocalDateTime var1 , LocalDateTime var2 , String msg){
        if (var1.isEqual(var2)){
            sendError(msg);
        }
        if (var1.isAfter(var2)){
            sendError(msg);
        }
    }

    /**
     * 时间 var1 小于等于 val2
     * @param var1 /
     * @param var2 /
     * @param msg /
     */
    public static void timeLtAndEquals(LocalDateTime var1 , LocalDateTime var2 , String msg){
        if (var1.isAfter(var2)){
            sendError(msg);
        }
    }

    /**
     * 时间 val1 等于时间 val2
     * @param var1 /
     * @param var2 /
     * @param msg /
     */
    public static void timeEquals(LocalDateTime var1 , LocalDateTime var2 , String msg){
        if (!var1.isEqual(var2)){
            sendError(msg);
        }
    }

    /**
     * 时间 val1 不等于时间 val2
     * @param var1 /
     * @param var2 /
     * @param msg /
     */
    public static void timeNotEquals(LocalDateTime var1 , LocalDateTime var2 , String msg){
        if (var1.isEqual(var2)){
            sendError(msg);
        }
    }

    /**
     * id 值不为 null , 且必须大于0
     * @param id /
     * @param msg /
     */
    public static void isLongId(Long id , String msg){
        notNull(id,msg);
        if (id < 1){
            sendError(msg);
        }
    }

    /**
     * id 值不为 null , 且必须大于0
     * @param id /
     * @param msg /
     */
    public static void isIntegerId(Integer id , String msg){
        notNull(id,msg);
        if (id < 1){
            sendError(msg);
        }
    }

    /**
     * 验证对象值相等
     * @param val1 对象1
     * @param val2 对象2
     * @param msg 消息
     * @param <T> 保证是同一对象
     */
    public static<T> void objEquals(T val1 , T val2 , String msg){
        if (!Objects.equals(val1,val2)){
            sendError(msg);
        }
    }

    /**
     * 验证对象值不相等
     * @param val1 对象1
     * @param val2 对象2
     * @param msg 消息
     * @param <T> 保证是同一对象
     */
    public static<T> void objNotEquals(T val1 , T val2 , String msg){
        if (Objects.equals(val1,val2)){
            sendError(msg);
        }
    }

    /**
     * 数字类型等于
     * @param n1 /
     * @param n2 /
     * @param msg 错误提示
     */
    public static void numberEq(Number n1 , Number n2 , String msg){
        if (new BigDecimal(n1.toString()).compareTo(new BigDecimal(n2.toString())) != 0){
            sendError(msg);
        }
    }

    /**
     * 数字类型不等于
     * @param n1 /
     * @param n2 /
     * @param msg 错误提示
     */
    public static void numberNotEq(Number n1 , Number n2 , String msg){
        if (new BigDecimal(n1.toString()).compareTo(new BigDecimal(n2.toString())) == 0){
            sendError(msg);
        }
    }

    /**
     * 数字类型大于 n1 > n2
     * @param n1 /
     * @param n2 /
     * @param msg 错误提示
     */
    public static void numberGt(Number n1 , Number n2 , String msg){
        if (new BigDecimal(n1.toString()).compareTo(new BigDecimal(n2.toString())) <= 0){
            sendError(msg);
        }
    }

    /**
     * 数字类型大于等于 n1 >= n2
     * @param n1 /
     * @param n2 /
     * @param msg 错误提示
     */
    public static void numberGe(Number n1 , Number n2 , String msg){
        if (new BigDecimal(n1.toString()).compareTo(new BigDecimal(n2.toString())) < 0){
            sendError(msg);
        }
    }

    /**
     * 数字类型小于 n1 < n2
     * @param n1 /
     * @param n2 /
     * @param msg 错误提示
     */
    public static void numberLt(Number n1 , Number n2 , String msg){
        if (new BigDecimal(n1.toString()).compareTo(new BigDecimal(n2.toString())) >= 0){
            sendError(msg);
        }
    }

    /**
     * 数字类型小于等于 n1 <= n2
     * @param n1 /
     * @param n2 /
     * @param msg 错误提示
     */
    public static void numberLe(Number n1 , Number n2 , String msg){
        if (new BigDecimal(n1.toString()).compareTo(new BigDecimal(n2.toString())) > 0){
            sendError(msg);
        }
    }

    /**
     * 集合为空
     * @param collection 集合
     * @param msg 错误提示
     */
    public static void collectionIsEmpty(Collection<?> collection , String msg){
        if (collection!=null && collection.size() != 0){
            sendError(msg);
        }
    }

    /**
     * 集合不为空
     * @param collection 集合
     * @param msg 错误提示
     */
    public static void collectionIsNotEmpty(Collection<?> collection , String msg){
        if (collection == null || collection.size() == 0){
            sendError(msg);
        }
    }

    /**
     * map为空
     * @param map map
     * @param msg 错误提示
     */
    public static void mapIsEmpty(Map<?,?> map , String msg){
        if (!MapUtil.isEmpty(map)){
            sendError(msg);
        }
    }


    /**
     * map不为空
     * @param map map
     * @param msg 错误提示
     */
    public static void mapIsNotEmpty(Map<?,?> map , String msg){
        if (MapUtil.isEmpty(map)){
            sendError(msg);
        }
    }


    /**
     * 错误
     * @param msg /
     */
    public static void sendError(String msg){
        throw new VerifyException(msg);
    }


}
